home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / linuxcon.000 / linuxcon / linuxconf-1.6 / netconf / host.c < prev    next >
C/C++ Source or Header  |  1996-05-03  |  11KB  |  426 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "netconf.h"
  4. #include "internal.h"
  5. #include "../xconf/xconf.h"
  6. #include "../dnsconf/dnsconf.h"
  7. #include "netconf.m"
  8.  
  9. static NETCONF_HELP_FILE help_thishost ("thishost");
  10.  
  11. /*
  12.     Compose one entry of the menu.
  13.     Simply add the current value to the menu string
  14.     Return dst.
  15. */
  16. char *menu_setupopt(
  17.     char *dst,
  18.     const char *menu,
  19.     const char *curval)
  20. {
  21.     if (curval[0] == '\0') curval = "Not set";
  22.     sprintf (dst,"%s (%s)",menu,curval);
  23.     return dst;
  24. }
  25.  
  26. static void netconf_setoneinter (
  27.     DIALOG &dia,
  28.     INTER_INFO &itf,
  29.     const char *title)
  30. {
  31.     dia.newf_title ("",title);
  32.     dia.newf_str (MSG_U(F_PRIMNAME,"Primary name + domain"),itf.name);
  33.     dia.newf_str (MSG_U(F_ALIASES,"Aliases (opt)"),itf.others);
  34.     dia.newf_str (MSG_U(F_IPADR,"IP address"),itf.ipaddr);
  35.     dia.newf_str (MSG_U(F_NETADR,"Network address (opt)"),itf.network);
  36.     dia.newf_str (MSG_U(F_NETMASK,"Netmask (opt)"),itf.netmask);
  37. }
  38.  
  39. const int NB_ADAPTOR=4;
  40.  
  41.  
  42. /*
  43.     Validate IP number. An empty string is ok here.
  44. */
  45. static bool host_validip(const char *aip, bool ishost)
  46. {
  47.     bool ret = true;
  48.     if (aip[0] != '\0') ret = device_validip(aip,ishost);
  49.     return ret;
  50. }
  51.  
  52. /*
  53.     Validate the user input for one interface
  54. */
  55. static void netconf_itfok(INTER_INFO &itf, const char *msg, char *status)
  56. {
  57.     int name_empty = itf.name.is_empty();
  58.     int other_empty = itf.others.is_empty();
  59.     int ip_empty = itf.ipaddr.is_empty();
  60.     if (ip_empty){
  61.         if (!name_empty || !other_empty){
  62.             strcat (status,msg);
  63.             strcat (status,MSG_U(E_NEEDIP
  64.                 ,"\n\tYou must provide the IP number\n"
  65.                  "\tsince you provided a name\n"));
  66.         }
  67.     }else{
  68.         char lstatus[1000];
  69.         lstatus[0] = '\0';
  70.         if (!device_validip(itf.ipaddr.get(),true)){
  71.             strcat (lstatus,MSG_U(F_IVLDIP,"\tInvalid host IP number\n"));
  72.         }
  73.         if (!host_validip(itf.network.get(),false)){
  74.             strcat (lstatus,MSG_U(F_IVLDNETIP,"\tInvalid network IP number\n"));
  75.         }
  76.         if (!host_validip(itf.netmask.get(),false)){
  77.             strcat (lstatus,MSG_U(E_IVLMASK,"\tInvalid netwask\n"));
  78.         }
  79.         if (lstatus[0] != '\0'){
  80.             strcat (status,msg);
  81.             strcat (status,"\n");
  82.             strcat (status,lstatus);
  83.         }
  84.     }
  85. }
  86.  
  87. static void netconf_checknonet(INTER_INFO &itf)
  88. {
  89.     /* #Specification: netconf / basic host info / no IP for eth0
  90.         If the user do no put any IP address for the
  91.         first adaptor (ETH0), it may be because it is
  92.         a mistake, or because no network is available.
  93.  
  94.         In the later case, a good idea is to enter
  95.         the IP number 127.0.0.1. This has the advantage
  96.         that local networking will work (eg. export DISPLAY=host:0).
  97.  
  98.         We can't assume that this is what the user intent. One
  99.         thing is sure, it is better to have a IP address there.
  100.  
  101.         So we are asking for a confirmation to the user.
  102.     */
  103.     if (itf.ipaddr.is_empty()
  104.         && xconf_yesno (MSG_U(Q_NOIP,"Are you sure")
  105.             ,MSG_U(I_NOIP
  106.              ,"No IP address was entered for the first\n"
  107.              "ethernet adaptor. Either it is a mistake\n"
  108.              "(you forgot) or you don't have a network\n"
  109.              "adaptor at all.\n"
  110.              "\n"
  111.              "If you don't have any network adaptor,\n"
  112.              "it is a good idea to enter the IP number\n"
  113.              "127.0.0.1, which correspond to a dummy\n"
  114.              "internal network. This may help later with\n"
  115.              "network aware application such as X11.\n"
  116.              "\n"
  117.              "Do you want me to enter 127.0.0.1 for you ?")
  118.             ,help_thishost)==MENU_YES){
  119.         itf.ipaddr.setfrom ("127.0.0.1");
  120.     }
  121. }
  122.  
  123. /*
  124.     Edit the spec of the current host.
  125.     Return -1 if any error or the user abort the process.
  126. */
  127. static int netconf_edithost(HOSTINFO &info)
  128. {
  129.     /* #Specification: netconf / this host setup
  130.         The user can change fields for each adaptor.
  131.         #
  132.             primary name of this machine/adaptor
  133.             aliase names of this machine/adaptor
  134.             IP address
  135.             Network
  136.             Netmask
  137.         #
  138.     */
  139.     int ret = -1;
  140.     int nofield = 0;
  141.     DIALOG dia;
  142.     int i;
  143.     static const char *tbmsg[]={
  144.         MSG_U(T_FIRSTETH,"First ethernet adaptor"),
  145.         MSG_U(T_SECONDETH,"Second ethernet adaptor"),
  146.         MSG_U(T_THIRDETH,"Third ethernet adaptor"),
  147.         MSG_U(T_FOURTHETH,"Fourth ethernet adaptor")
  148.     };
  149.     for (i=0; i<NB_ADAPTOR; i++){
  150.         netconf_setoneinter (dia,info.a[i],tbmsg[i]);
  151.     }
  152.     while (1){
  153.         if (dia.edit(
  154.             MSG_U(T_THISHOST,"This host basic configuration")
  155.             ,MSG_U(I_THISHOST
  156.              ,"You are allowed to control the parameters\n"
  157.               "which are specific to this host and related\n"
  158.               "to its main connection to the local network\n")
  159.             ,help_thishost.getpath()
  160.             ,nofield) != MENU_ACCEPT){
  161.             break;
  162.         }else{
  163.             /* We must validate the input somehow */
  164.             char status[1000];
  165.             status[0] = '\0';
  166.             netconf_checknonet(info.a[0]);
  167.             for (i=0; i<NB_ADAPTOR; i++){
  168.                 netconf_itfok(info.a[i],tbmsg[i],status);
  169.             }
  170.             if (status[0] == '\0'){
  171.                 ret = 0;
  172.                 break;
  173.             }else{
  174.                 xconf_error ("%s",status);
  175.             }
  176.         }
  177.     }
  178.     if (ret == -1) dia.restore();
  179.     return ret;
  180. }
  181.  
  182.  
  183. /*
  184.     Make sure the loghost alias is in str. Add it if missing.
  185. */
  186. static void host_chkloghost(SSTRING &st, const char *loghost)
  187. {
  188.     /* #Specification: netconf / host alias / loghost
  189.         netconf make sure that the alias "loghost" is
  190.         always set for the current host. If it is missing
  191.         it will be added. netconf use this internally to
  192.         locate the host definition.
  193.     */
  194.     if (!host_lookupother(st.get(),loghost)){
  195.         char buf[1000];
  196.         sprintf (buf,"%s %s",st.get(),loghost);
  197.         st.setfrom (buf);
  198.     }
  199. }
  200.  
  201.  
  202. static void netconf_loadinfo (
  203.     INTER_INFO &itf,
  204.     HOSTS &hosts,
  205.     NETWORKS &networks,
  206.     const char *spcnamealias,    // Special alias NAM_ETHx_NAME
  207.     const char *netname,
  208.     const char *mskname)
  209. {
  210.     HOST *hst = hosts.getitem (spcnamealias);
  211.     HOST *net = networks.getitem (netname);
  212.     HOST *msk = networks.getitem (mskname);
  213.     if (hst != NULL){
  214.         itf.ipaddr.setfrom(hst->getipnum());
  215.         itf.others.setfrom(hst->getothers());
  216.         // It is possible that an entry only have the alias name
  217.         // There is no way to tell this just by reading /etc/hosts
  218.         // The primary name is simply the first of the list
  219.         // If the primary name is the special alias (loghost), we
  220.         // organise things here.
  221.         const char *name1 = hst->getname1();
  222.         if (strcmp(name1,spcnamealias)==0){
  223.             itf.others.append (" ");
  224.             itf.others.append (spcnamealias);
  225.         }else{
  226.             itf.name.setfrom (name1);
  227.         }
  228.     }
  229.     if (net != NULL) itf.network.setfrom(net->getipnum());
  230.     if (msk != NULL) itf.netmask.setfrom(msk->getipnum());
  231. }
  232.  
  233.  
  234. static void netconf_saveinfo (
  235.     INTER_INFO &itf,
  236.     HOSTS &hosts,
  237.     NETWORKS &networks,
  238.     const char *forcealias,
  239.     const char *netname,
  240.     const char *mskname)
  241. {
  242.     HOST *hst = hosts.getitem (forcealias);
  243.     HOST *net = networks.getitem (netname);
  244.     HOST *msk = networks.getitem (mskname);
  245.     if (!itf.name.is_empty()
  246.         || !itf.others.is_empty()
  247.         || !itf.ipaddr.is_empty()){
  248.         host_chkloghost(itf.others,forcealias);
  249.         if (hst == NULL){
  250.             hst = new HOST;
  251.             hosts.add (hst);
  252.         }
  253.         hst->setname1 (itf.name.get());
  254.         hst->setipnum (itf.ipaddr.get());
  255.         hst->setothers(itf.others.get());
  256.     }else if (hst != NULL){
  257.         hosts.remove (hst);
  258.         delete hst;
  259.     }
  260.     if (!itf.network.is_empty()){
  261.         if (net == NULL){
  262.             net = new NETWORK;
  263.             networks.add (net);
  264.         }
  265.         net->setname1 (netname);
  266.         net->setipnum (itf.network.get());
  267.     }else if (net != NULL){
  268.         networks.remove (net);
  269.         delete net;
  270.     }
  271.     if (!itf.netmask.is_empty()){
  272.         if (msk == NULL){
  273.             msk = new NETWORK;
  274.             networks.add (msk);
  275.         }
  276.         msk->setname1 (mskname);
  277.         msk->setipnum (itf.netmask.get());
  278.     }else if (msk != NULL){
  279.         networks.remove (msk);
  280.         delete msk;
  281.     }
  282. }
  283.  
  284.  
  285. DEVICE_NAME_INFO dev_name_info[]={
  286.     {NAM_ETH0_LOGHOST,NAM_ETH0_NETWORK,NAM_ETH0_NETMASK},
  287.     {NAM_ETH1_LOGHOST,NAM_ETH1_NETWORK,NAM_ETH1_NETMASK},
  288.     {NAM_ETH2_LOGHOST,NAM_ETH2_NETWORK,NAM_ETH2_NETMASK},
  289.     {NAM_ETH3_LOGHOST,NAM_ETH3_NETWORK,NAM_ETH3_NETMASK},
  290. };
  291.  
  292. /*
  293.     Load all basic information for all the adaptor from
  294.     /etc/hosts and /etc/networks
  295.  
  296.     Return -1 if any error.
  297. */
  298. static int netconf_loadinfos(
  299.     HOSTS &hosts,
  300.     NETWORKS &networks,
  301.     HOSTINFO &info)
  302. {
  303.     int ret = -1;
  304.     if (hosts.read () != -1
  305.         && networks.read() != -1){
  306.         int i;
  307.         for (i=0; i<NB_ADAPTOR; i++){
  308.             netconf_loadinfo (info.a[i],hosts,networks
  309.                 ,dev_name_info[i].host
  310.                 ,dev_name_info[i].net
  311.                 ,dev_name_info[i].mask);
  312.         }
  313.         ret = 0;
  314.     }
  315.     return ret;
  316. }
  317. /*
  318.     Load all basic information for all the adaptors from
  319.     /etc/hosts and /etc/networks
  320.  
  321.     Return -1 if any error.
  322.  
  323. */
  324. int netconf_loadinfos(HOSTINFO &info)
  325. {
  326.     HOSTS hosts;
  327.     NETWORKS networks;
  328.     return netconf_loadinfos(hosts,networks,info);
  329. }
  330. /*
  331.     Update the local DNS (if present) from the host information
  332. */
  333. static void netconf_updatedns(HOSTINFO &info, int silent)
  334. {
  335.     const char *tbip[NB_ADAPTOR];
  336.     int nbip = 0;
  337.     int ok = 0;
  338.     for (int i=0; i<NB_ADAPTOR; i++){
  339.         INTER_INFO *itf = &info.a[i];
  340.         if (!itf->ipaddr.is_empty()){
  341.             const char *ip = itf->ipaddr.get();
  342.             if (itf->name.is_empty()){
  343.                 tbip[nbip++] = ip;
  344.             }else{
  345.                 const char *tb[1];
  346.                 tb[0] = ip;
  347.                 ok |= dnsconf_condset (itf->name.get(),tb,1);
  348.             }
  349.         }
  350.     }
  351.     if (nbip > 0 && !info.a[0].name.is_empty()){
  352.         ok |= dnsconf_condset (info.a[0].name.get(),tbip,nbip);
  353.     }
  354.     if (ok && !silent){
  355.         xconf_notice(MSG_U(N_DNSUPDATED,"The DNS has been updated"));
  356.     }
  357. }
  358. /*
  359.     Update the local DNS (if present) from the host information
  360. */
  361. void netconf_updatedns()
  362. {
  363.     HOSTINFO info;
  364.     if (netconf_loadinfos(info)!=-1){
  365.         netconf_updatedns(info,1);
  366.     }
  367. }
  368.  
  369. /*
  370.     Edit the spec of the current host
  371. */
  372. void netconf_edithost()
  373. {
  374.     /* #Specification: hostname / where is it stored
  375.         netconf use the plain /etc/hosts file to store
  376.         more of the name information. There is no other
  377.         file such as /etc/hostname or /etc/HOSTNAME.
  378.  
  379.         netconf assume that special entries in /etc/hosts
  380.         will have known alias name. It will enforce the presence
  381.         of those alias name.
  382.  
  383.         The primary name of the machine will be taken from
  384.         the entry which the alias "loghost". This name and
  385.         IP number will be used for the first ethernet adaptor (ETH0).
  386.  
  387.         The second ethernet adaptor will be located from the
  388.         entry having the alias eth1_loghost. The third ethernet
  389.         adaptor spec will be located from the entry having the
  390.         alias eth2_loghost.
  391.  
  392.     */
  393.     /* #Specification: adaptor setup / Token ring and others
  394.         netconf does not manage such systems for now.
  395.     */
  396.     HOSTS hosts;
  397.     NETWORKS networks;
  398.     HOSTINFO info;
  399.     if (netconf_loadinfos(hosts,networks,info)!=-1){
  400.         if (netconf_edithost (info) != -1){
  401.             for (int i=0; i<NB_ADAPTOR; i++){
  402.                 netconf_saveinfo (info.a[i],hosts,networks
  403.                     ,dev_name_info[i].host
  404.                     ,dev_name_info[i].net
  405.                     ,dev_name_info[i].mask);
  406.             }
  407.             hosts.write();
  408.             networks.write ();
  409.             /* #Specification: netconf / basic host info / DNS
  410.                 Each time we update the basic host info
  411.                 (name and IP number of the adaptor), we
  412.                 synchronise the info in the DNS on this
  413.                 machine is one is available.
  414.  
  415.                 This is done silently. Maybe we should
  416.                 let the user decide if he wants to update
  417.                 the DNS from that info. Why ?
  418.             */
  419.             netconf_updatedns(info,0);
  420.         }
  421.     }
  422. }
  423.     
  424.  
  425.  
  426.